/*
 * idt.h
 * 
 * Interrupt Descriptor Table
 * 
 */

#ifndef __IDT_H__
#define __IDT_H__

#include <types.h>

#define IDT_LENGTH	128		// Cuidado que este valor tambien esta definido en isr_handlers.asm

#define IDT_OK				0x0
#define IDT_BAD_INDEX		0x1
#define IDT_INDEX_IN_USE	0x2

/* Indices de interrupciones */

#define IDT_INDEX_GENERALPROT	0x0C
#define IDT_INDEX_PAGEFAULT		0x0D
#define IDT_INDEX_TIMERTICK		0x20
#define IDT_INDEX_KEYBOARD		0x21
#define IDT_INDEX_SYSCALL		0x80

/* Campos del descriptor de IDT */

#define IDT_DESC_OFFSET(offset) ((uint_64)(BITS_00_15 & (uint_32)(offset)) | ((uint_64)(BITS_16_31 & (uint_32)(offset)) << 32))

#define IDT_DESC_SEGSEL(seg) 	((uint_64)(BITS_00_15 & (uint_64)(seg)) << 16)	// Selector de Segmento

#define IDT_DESC_TYPE(type) 	(((uint_64)(type)) << (32 + 8))
#define IDT_DESC_DPL(level)		(((uint_64)(level)) << (32 + 13))		// Nivel de Privilegio del Descriptor
#define IDT_DESC_P 				((uint_64) 1 << (32 + 15))				// Segmento Presente

#define IDT_NULL ((uint_64) 0)

/* Tipos de descriptores */

#define IDT_TYPE_S_16BTSSA 	0x1 	// 16-bit TSS (Available)
#define IDT_TYPE_S_LDT      0x2 	// LDT
#define IDT_TYPE_S_16BTSSB  0x3 	// 16-bit TSS (Busy)
#define IDT_TYPE_S_16BCG    0x4 	// 16-bit Call Gate
#define IDT_TYPE_S_TG       0x5 	// Task Gate
#define IDT_TYPE_S_16BIG    0x6 	// 16-bit Interrupt Gate
#define IDT_TYPE_S_16BTG    0x7 	// 16-bit Trap Gate
									// Reserved
#define IDT_TYPE_S_32BTSSA  0x9 	// 32-bit TSS (Available)
									// Reserved
#define IDT_TYPE_S_32BTSSB  0xB 	// 32-bit TSS (Busy)
#define IDT_TYPE_S_32BCG    0xC 	// 32-bit Call Gate
#define IDT_TYPE_S_32BIG    0xE 	// 32-bit Interrupt Gate
#define IDT_TYPE_S_32BTG    0xF 	// 32-bit Trap Gate


/* Estructura del IDT Register */

#include <stdint.h>

typedef struct idt_reg
{ 
    uint16_t idt_length;
    uint32_t idt_addr;
} __attribute__((__packed__)) idt_reg; 

/* Exports */

void idt_init();
uint_32 idt_register(uint_32 indice, void* handler);

#endif /* __IDT_H__ */
